package com.guqj.basis.clone;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * <p>
 * 	深复制(深克隆)被复制对象的所有变量都含有与原来的对象相同的值，除去那些引用其他对象的变量，那些引用其他对象的变量将指向被复制过的新对象，而不再试原有的那些被引用的对象,
 * 	换言之，深复制把要复制的对象所引用的对象都复制了一遍。(复制值)
 * </p>
 * @author guqj
 * @date   2017年3月10日
 */
public class PeopleDeep implements Serializable {

	private static final long serialVersionUID = -1497197729080301378L;
	private String name;
	private Integer age;
	private Address address; // 被克隆对象所共享

	public PeopleDeep(String name, int age, Address address) {
		this.name = name;
		this.age = age;
		this.address = address;
	}

	protected Object clone() throws CloneNotSupportedException {
		try {
			// 将对象写入流中
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(bos);
			oos.writeObject(this);

			// 从流中读取对象
			ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bis);
			return ois.readObject();
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void main(String[] args) throws CloneNotSupportedException {
		Address address = new Address("中国", "上海", "上海");
		PeopleDeep p1 = new PeopleDeep("xiaoxiao", 20, address);
		PeopleDeep p2 = (PeopleDeep) p1.clone();
		p2.name = "lili";
		p2.age = 30;
		p2.address.setCity("闵行");
		System.out.println(p1 == p2);
		System.out.println("p1 age: " + p1.age);
		System.out.println("p1 address city: " + p1.address.getCity()); // p1.address.getCity()值不会随着p2改变而改变
	}
}
